/**
 * 模拟常见高阶函数
 */
export {}

interface MapFunc {
  <T>(arr: T[], fn: (item: T) => T): T[];
}
interface EverySomeFunc {
  <T>(arr: T[], fn: (item: T) => boolean): boolean;
}
interface ReduceFunc {
  <T, U>(arr: T[], fn: (acc: U, item: T) => U, acc: U): U;
}

let arr: number[] = [1, 2, 3, 4, 5]

// 模拟map
const map: MapFunc = <T>(arr: T[], fn: (item: T) => T): T[] => {
  let res: T[] = []
  for (let value of arr) {
    res.push(fn(value))
  }
  return res
}

let res1 = map(arr, n => n * 2)
console.log(res1)

// 模拟every
const every: EverySomeFunc = <T>(arr: T[], fn: (item: T) => boolean): boolean =>{
  let res = true
  for (let value of arr) {
    // 有一个false则返回false
    if (!fn(value)) {
      res = false
      break
    }
  }
  return res
}

let res2 = every(arr, n => n > 2)
console.log(res2)

// 模拟some
const some: EverySomeFunc = <T>(arr: T[], fn: (item: T) => boolean): boolean => {
  let res = false
  for (let value of arr) {
    // 有一个true则返回false
    if (fn(value)) {
      res = true
      break
    }
  }
  return res
}

let res3 = some(arr, n => n > 2)
console.log(res3)

// 模拟reduce
const reduce: ReduceFunc = <T, U>(arr: T[], fn: (acc: U, value: T) => U, accumulator: U): U => {
  for (let value of arr) {
    accumulator = fn(accumulator, value)
  }
  return accumulator
}

let res4 = reduce(arr, (a, b) => a + b, 0)

console.log(res4)
